package com.davidlife.javase.annotation;

/*
#### JDK中预定义的一些注解
* @Override
* @Deprecated：如，Date类中就有很多方法都标注为Deprecated了
* @SuppressWarnings:压制警告
    + @SuppressWarnings("all")

#### 自定义注解
* 格式：
    ```
    元注解
    public @interface MyAnno{
        属性列表;
    }
    ```
* 本质：注解本质上就是一个接口，该接口默认继承自`java.lang.annotation.Annotation`接口。
    使用javac编译后，**javap**反编译可查看编译后的MyAnno.class内容为：`public interface MyAnno extends java.lang.annotation.Annotation {}`
* 注解的属性：**就是接口中的抽象方法**。因为注解其实就是接口，所以接口中能定义的就可在注解中定义。（注解中定义常量没什么用）。
* 注解属性的几点要求：
    + 属性的返回值类型只能是下列取值：
        * 基本数据类型
        * String
        * 枚举
        * 注解
        * 以上类型的数组
        * （注意不能是void或其他的类）
    + 定义了属性，在使用时需要给属性赋值
        * 如果定义属性时使用default关键字给属性默认初始化值，则使用注解时，可以不进行属性的赋值。
        * 如果只有一个属性需要赋值，并且属性的名称是value，则value可以省略，直接定义值即可。
        * 数组作为属性给其赋值时，值使用{}包裹，如果数组中只有一个值，则{}可省略。
 */
public @interface MyAnno {
    int age();

    /*
    如果定义属性时使用default关键字给属性默认初始化值，则使用注解时，可以不进行属性的赋值。
     */
    String name() default "zhangsan";

    /*如果只有一个属性需要赋值，并且属性的名称是value，则value可以省略，直接定义值即可。*/
    String value();

    Season season();  //枚举属性

    MyAnno2 anno();   //注解属性

    String[] strs();
}

enum Season {
    Spring, Summary, Autumn, Winter
}

//name属性不用赋值了，因为他有默认值
//如果不是只有value一个属性，且value没有默认值，则value属性也是要手动赋值的。
//数组作为属性给其赋值时，值使用{}包裹，如果数组中只有一个值，则{}可省略。比如这里可写为 strs = "aa"
@MyAnno(age=18, value = "testValue", season = Season.Autumn, anno = @MyAnno2, strs = {"aa", "bbb", "c"})
class MyClass {

}